package com.netty.cn.model.MoreClient.client;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netty.cn.rpc.jboss.factory.MarshallingCodeCFactory;
import com.netty.cn.rpc.jboss.model.SubscribeReq;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class NettyClient {
private static Logger log = LoggerFactory.getLogger(NettyClient.class);    
    
    public static Map<String, ChannelFuture> channels = null;
    
    private static EventLoopGroup group = new NioEventLoopGroup();
    
    private static  Bootstrap bootstrap=null; 
    
    /**
     * 初始化Bootstrap
     */
    public static final void getBootstrap() {

    	if(bootstrap==null) {
    		bootstrap = new Bootstrap();
            bootstrap.group(group)
                     .channel(NioSocketChannel.class)
                     .option(ChannelOption.TCP_NODELAY, true)
                     .handler(new ChannelInitializer<SocketChannel>() {
                    	 @Override
                         public void initChannel(SocketChannel ch)
                                 throws Exception {
                             ch.pipeline().addLast(
                                     MarshallingCodeCFactory.buildMarshallingDecoder());
                             ch.pipeline().addLast(
                                     MarshallingCodeCFactory.buildMarshallingEncoder());
                             ch.pipeline().addLast(new MoreClientHandler());
                         }
            });
    	}
    	
    }
 
    //二次重连
    public static final Map<String , ChannelFuture> twoGetChannel(List<Map<String,Object>> portHosts){
        
    	group.shutdownGracefully();
        
    	group = new NioEventLoopGroup();
        
        return getChannel(portHosts);
    }
    
    
    //   获取所有连接
    public static final Map<String , ChannelFuture> getChannel(List<Map<String,Object>> portHosts) {
        Map<String , ChannelFuture> result = new HashMap<>();
        getBootstrap();
        
        for (Map<String, Object> map : portHosts) {
            String host = (String) map.get("IP");
            int port = Integer.valueOf((String) map.get("PORT"));
            try {
				bootstrap.remoteAddress(host, port);
				//异步连接tcp服务端
				ChannelFuture future = bootstrap.connect().addListener((ChannelFuture futureListener) -> {
//                final EventLoop eventLoop = futureListener.channel().eventLoop();
				    if (!futureListener.isSuccess()) {
				         
				        log.info("与"+host+":"+port+"连接失败!");

				    }
				});
				future.await();  //等待连接成功
				result.put(host+":"+port, future);
				
			} catch (Exception e) {
				log.error("Connection Host:"+host+":"+port+" Error"+e.toString(),e);
			}
        }
        return result;
    }
 
    //发送消息
    public static void sendMsg(ChannelFuture future, String msg) throws InterruptedException  {
        if (future != null && future.channel().isActive()) {
            
            Channel channel = future.channel();
            InetSocketAddress ipSocket = (InetSocketAddress) channel.remoteAddress();
            String host = ipSocket.getHostString();
            int port = ipSocket.getPort();
            System.out.println("向设备" + host+":"+port+"发送数据");
            
            //项目封装的util类
//            byte[] msgbytes = ByteUtil.hexStringToBytes(msg);
//            ByteBuf buf = Unpooled.buffer();
//            buf.writeBytes(msgbytes);
            
            SubscribeReq req = new SubscribeReq();
            req.setAddress("Beijing Jiaotong University, BeiJing ");
            req.setPhoneNumber("010-5168****");
            req.setProductName("手动发送消息，"+host+" port:"+port);
            req.setSubReqID(123);
            req.setUserName("LMRZero");

            // 2.写数据
            future.channel().writeAndFlush(req).sync();
            log.info("发送消息成功");
        }else {
        	log.info("发送消息失败");
        }
    }
 

}
